{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "开始计算中继节点的Oblivious方案\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "开始计算中继节点的Oblivious方案\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "开始计算中继节点的Oblivious方案\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "开始计算中继节点的Oblivious方案\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "开始计算中继节点的Oblivious方案\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "开始计算中继节点的Oblivious方案\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "开始计算中继节点的Oblivious方案\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "开始计算中继节点的Oblivious方案\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n",
      "清除Alpha\n"
     ]
    }
   ],
   "source": [
    "from cluster_qkd_networkx_cluster import XMultiClusterQKDNetwork\n",
    "from tool import getGraphWithTemplate\n",
    "from itertools import combinations\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import random\n",
    "\n",
    "variable_node_nums_congestion_ratio = {\"Round\":[], \"SPS\":[], \"OGS\":[], \"ORDP\":[]} #拥塞率\n",
    "variable_node_nums_resource_utilization = {\"Round\":[], \"SPS\":[], \"OGS\":[], \"ORDP\":[]} #资源利用率\n",
    "variable_node_nums_jains_index = {\"Round\":[], \"SPS\":[], \"OGS\":[], \"ORDP\":[]} #公平性\n",
    "variable_capacity_congestion_ratio = {\"Round\":[], \"SPS\":[], \"OGS\":[], \"ORDP\":[]} #拥塞率\n",
    "variable_capacity_resource_utilization = {\"Round\":[], \"SPS\":[], \"OGS\":[], \"ORDP\":[]} #资源利用率\n",
    "variable_capacity_jains_index = {\"Round\":[], \"SPS\":[], \"OGS\":[], \"ORDP\":[]} #公平性\n",
    "\n",
    "for round_idx in range(8):\n",
    "    sinle_cluster_size = 8\n",
    "    cluster_number = round_idx * 5 + 5\n",
    "    template_number = 9\n",
    "\n",
    "    numbers = list(range(1, sinle_cluster_size*cluster_number+1))\n",
    "    nested_list = [numbers[i:i+sinle_cluster_size] for i in range(0, len(numbers), sinle_cluster_size)]\n",
    "    template_file_names = [f\"cluster{(i%template_number)+1}.txt\" for i in range(cluster_number)]\n",
    "    graph = getGraphWithTemplate(sinle_cluster_size, cluster_number, template_file_names)\n",
    "    qkdnx = XMultiClusterQKDNetwork(\n",
    "        graph, \n",
    "        nested_list, \n",
    "        read_from_pkl=False, \n",
    "        read_from_template=True, #是否从pkl文件里面读XCluster\n",
    "        template_file_names=template_file_names\n",
    "    ) \n",
    "\n",
    "    cplex_alphas_total = []\n",
    "    spf_alphas_total = []\n",
    "    online_greedy_alphas_total = []\n",
    "\n",
    "    cplex_ru_total = []\n",
    "    spf_ru_total = []\n",
    "    online_greedy_ru_total = []\n",
    "\n",
    "    cplex_jains_index_total = []\n",
    "    spf_jains_index_total = []\n",
    "    online_greedy_jains_index_total = []\n",
    "\n",
    "    cplex_alphas = []\n",
    "    spf_alphas = []\n",
    "    online_greedy_alphas = []\n",
    "\n",
    "    cplex_ru = []\n",
    "    spf_ru = []\n",
    "    online_greedy_ru = []\n",
    "\n",
    "    cplex_jains_index = []\n",
    "    spf_jains_index = []\n",
    "    online_greedy_jains_index = []\n",
    "\n",
    "    for _ in range(20):\n",
    "        cplex_alphas = []\n",
    "        spf_alphas = []\n",
    "        online_greedy_alphas = []\n",
    "\n",
    "        cplex_ru = []\n",
    "        spf_ru = []\n",
    "        online_greedy_ru = []\n",
    "\n",
    "        cplex_jains_index = []\n",
    "        spf_jains_index = []\n",
    "        online_greedy_jains_index = []\n",
    "\n",
    "        def generateBrokenLinkList() -> list:\n",
    "            broken_list = []\n",
    "            for node_ids in qkdnx.clusterListArr:\n",
    "                candidate_pair = []\n",
    "                if(len(node_ids)<3):\n",
    "                    continue\n",
    "                for u, v in combinations(node_ids, 2):\n",
    "                    if graph.has_edge(u, v):\n",
    "                        candidate_pair.append([u,v])\n",
    "                broken_list.append(random.choice(candidate_pair))\n",
    "            return broken_list\n",
    "        # 跑100轮，测均值\n",
    "        for i in range(1000):\n",
    "            clusterNum = qkdnx.getClusterNum()\n",
    "            _startClusterID = random.randint(1, clusterNum)\n",
    "            _endClusterID = random.randint(1, clusterNum)\n",
    "            startNodeID = random.randint(1, len(qkdnx.clusterListArr[_startClusterID-1]))\n",
    "            endNodeID = random.randint(1, len(qkdnx.clusterListArr[_endClusterID-1]))\n",
    "            qkdnx.requestFlow(\n",
    "                startClusterID = _startClusterID, \n",
    "                startNodeID = startNodeID, \n",
    "                endClusterID = _endClusterID, \n",
    "                endNodeID = endNodeID, \n",
    "                flow = random.randint(0, 50), \n",
    "                brokenLinks = generateBrokenLinkList(), \n",
    "            )\n",
    "\n",
    "        cplex_alphas.append(qkdnx.maxCplexAlpha)\n",
    "        spf_alphas.append(qkdnx.maxSPFAlpha)\n",
    "        online_greedy_alphas.append(qkdnx.maxOnlineGreedyAlpha)\n",
    "\n",
    "        ru_data = qkdnx.getResourceUtilization()\n",
    "        cplex_ru.append(ru_data[0])\n",
    "        spf_ru.append(ru_data[1])\n",
    "        online_greedy_ru.append(ru_data[2])\n",
    "\n",
    "        jain_index_data = qkdnx.getJainsIndex()\n",
    "        cplex_jains_index.append(jain_index_data[0])\n",
    "        spf_jains_index.append(jain_index_data[1])\n",
    "        online_greedy_jains_index.append(jain_index_data[2])\n",
    "\n",
    "        qkdnx.setNetXFlowZero()\n",
    "        print(\"清除Alpha\")\n",
    "\n",
    "    cplex_alphas_total.append(np.mean(cplex_alphas))\n",
    "    spf_alphas_total.append(np.mean(spf_alphas))\n",
    "    online_greedy_alphas_total.append(np.mean(online_greedy_alphas))\n",
    "\n",
    "    cplex_ru_total.append(np.mean(cplex_ru))\n",
    "    spf_ru_total.append(np.mean(spf_ru))\n",
    "    online_greedy_ru_total.append(np.mean(online_greedy_ru))\n",
    "\n",
    "    cplex_jains_index_total.append(np.mean(cplex_jains_index))\n",
    "    spf_jains_index_total.append(np.mean(spf_jains_index))\n",
    "    online_greedy_jains_index_total.append(np.mean(online_greedy_jains_index))\n",
    "    \n",
    "    variable_node_nums_congestion_ratio[\"Round\"].append(cluster_number * sinle_cluster_size)\n",
    "    variable_node_nums_resource_utilization[\"Round\"].append(cluster_number * sinle_cluster_size)\n",
    "    variable_node_nums_jains_index[\"Round\"].append(cluster_number * sinle_cluster_size)\n",
    "\n",
    "    variable_node_nums_congestion_ratio[\"ORDP\"].append(np.mean(cplex_alphas_total))\n",
    "    variable_node_nums_congestion_ratio[\"SPS\"].append(np.mean(spf_alphas_total))\n",
    "    variable_node_nums_congestion_ratio[\"OGS\"].append(np.mean(online_greedy_alphas_total))\n",
    "\n",
    "    variable_node_nums_resource_utilization[\"ORDP\"].append(np.mean(cplex_ru_total))\n",
    "    variable_node_nums_resource_utilization[\"SPS\"].append(np.mean(spf_ru_total))\n",
    "    variable_node_nums_resource_utilization[\"OGS\"].append(np.mean(online_greedy_ru_total))\n",
    "\n",
    "    variable_node_nums_jains_index[\"ORDP\"].append(np.mean(cplex_jains_index_total))\n",
    "    variable_node_nums_jains_index[\"SPS\"].append(np.mean(spf_jains_index_total))\n",
    "    variable_node_nums_jains_index[\"OGS\"].append(np.mean(online_greedy_jains_index_total))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'Round': [40, 80, 120, 160, 200, 240, 280, 320],\n",
       " 'SPS': [159.6,\n",
       "  49.36363636363637,\n",
       "  36.2,\n",
       "  24.666666666666668,\n",
       "  19.833333333333332,\n",
       "  20.8,\n",
       "  15.8,\n",
       "  19.833333333333332],\n",
       " 'OGS': [242.0, 127.4, 83.6, 90.4, 52.6, 55.333333333333336, 37.4, 31.0],\n",
       " 'ORDP': [22.70301414465743,\n",
       "  19.4,\n",
       "  21.4,\n",
       "  11.642857142857142,\n",
       "  15.25,\n",
       "  14.777777777777779,\n",
       "  21.833333333333332,\n",
       "  14.0]}"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "variable_node_nums_congestion_ratio"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'Round': [40, 80, 120, 160, 200, 240, 280, 320],\n",
       " 'SPS': [0.061661185336398534,\n",
       "  0.0801013689376889,\n",
       "  0.05507619072481045,\n",
       "  0.049028134251258175,\n",
       "  0.037983465702190224,\n",
       "  0.02707469740986232,\n",
       "  0.026345587788038922,\n",
       "  0.016843625893829216],\n",
       " 'OGS': [0.07496218195317002,\n",
       "  0.08277644990547887,\n",
       "  0.07993179382434167,\n",
       "  0.04995359964446375,\n",
       "  0.055880699094373876,\n",
       "  0.04512128546924109,\n",
       "  0.05146090806771949,\n",
       "  0.049721813836977755],\n",
       " 'ORDP': [0.38750704135708647,\n",
       "  0.19036203623608988,\n",
       "  0.0945738141499836,\n",
       "  0.10806695714767924,\n",
       "  0.05522664439994624,\n",
       "  0.0448478100208038,\n",
       "  0.022629658462141215,\n",
       "  0.027034423697536163]}"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "variable_node_nums_resource_utilization"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'Round': [40, 80, 120, 160, 200, 240, 280, 320],\n",
       " 'SPS': [0.28614555623508303,\n",
       "  0.3240244004083558,\n",
       "  0.2740892642385659,\n",
       "  0.2534583330329368,\n",
       "  0.211757637557884,\n",
       "  0.15680322987540588,\n",
       "  0.1413664695454486,\n",
       "  0.10707420587410033],\n",
       " 'OGS': [0.254737103643475,\n",
       "  0.20149031477068494,\n",
       "  0.19362018958078053,\n",
       "  0.16560123401869603,\n",
       "  0.15240065096994782,\n",
       "  0.13310320367400727,\n",
       "  0.13149085990103493,\n",
       "  0.11999803229555565],\n",
       " 'ORDP': [0.7173554787144992,\n",
       "  0.6009574673377225,\n",
       "  0.44309401347237565,\n",
       "  0.3690341627770943,\n",
       "  0.27412262528015496,\n",
       "  0.22424832777028184,\n",
       "  0.17228337018182116,\n",
       "  0.154148904370003]}"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "variable_node_nums_jains_index"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "cplex",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
